프로젝트 생성 안드로이드 내에서 권한을 획득해보겠습니다. 암묵적 인텐트 중에 ACTION_CALL은 전화를 거는 권한이 없어서 수행할 수 없었습니다. 이번엔 권한을 획득하고 전화를 걸어보겠습니다. Call App 이라는 이름으로 프로젝트를 생성해보겠습니다.
권한을 얻기 위한 준비 마시멜로우(Marshmallow) 이전 버전 1. AndroidMenifest.xml에 <uses-permission /> 을 작성해줘야한다.
마시멜로우(Marshmallow) 버전 1. AndroidMenifest.xml에 <uses-permission /> 을 작성해줘야한다. 2. 실시간으로 권한을 허가하는 작업이 필요하다.
필요 로직 버전이 마시멜로우인지 확인한다. 마시멜로우가 맞다면, 이 전에 권한에 대한 허가를 한 적이 있는지 확인한다. 허가한 적이 있으면 작업을 수행한다. 허가한 적이 없으면 거부한 적이 있는지 확인한다. 거부한적이 있으면 사용할수 있는 권한이 무엇인지 개발자에게 알려주고 사용할지 물어본다. 거부한적이 없으면 권한을 요청한다.
버튼 만들기 ACTION_CALL을 하기 위한 버튼을 만듭니다.
Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="전화 걸기"
android:id="@+id/button"
android:layout_below="@+id/textView"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
ACTION_CALL 버튼을 MainActivity에서 만든다.
public class MainActivity extends AppCompatActivity {
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:010-1111-2222"));
startActivity(intent);
}
});
}
}
권한 주기 Manifest.xml에 permission을 추가합니다. <uses-permission android:name="android.permission.CALL_PHONE" />
로직 작성
public class MainActivity extends AppCompatActivity {
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
int permissionResult = checkSelfPermission(Manifest.permission.CALL_PHONE);
if (permissionResult == PackageManager.PERMISSION_DENIED) {
if (shouldShowRequestPermissionRationale(Manifest.permission.CALL_PHONE)) {
AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);
dialog.setTitle("권한이 필요합니다.")
.setMessage("이 기능을 사용하기 위해서는 단말기의 \"전화걸기\" 권한이 필요합니다. 계속 하시겠습니까?")
.setPositiveButton("네", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.CALL_PHONE}, 1000);
}
}
})
.setNegativeButton("아니요", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this, "기능을 취소했습니다", Toast.LENGTH_SHORT).show();
}
})
.create()
.show();
}
else {
requestPermissions(new String[]{Manifest.permission.CALL_PHONE}, 1000);
}
}
else {
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:010-1111-2222"));
startActivity(intent);
}
}
else {
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:010-1111-2222"));
startActivity(intent);
}
}
});
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == 1000) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:010-1111-2222"));
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
startActivity(intent);
}
} else {
Toast.makeText(MainActivity.this, "권한요청을 거부했습니다.", Toast.LENGTH_SHORT).show();
}
}
}
}
안드로이드는 패키지를 아이디로 갖는다.
실행 하기 전화걸기 버튼을 눌러보겠습니다.
권한에 대한 요청이 나타납니다. DENY 해보겠습니다.
거부한 뒤 다시 버튼을 누르면 이미 거부되어 있기 때문에 권한이 왜 필요한지 설명해줍니다.
권한이 왜 필요한지 확인 한 뒤 "네"를 누르면 다시 권한요청이 나타납니다. [ALLOW]를 눌러 권한을 허락합니다.
권한을 허락했더니 이제 전화가 걸립니다!
클래스로 따로 만들기 PermissionRequester.java 클래스를 만들어 보겠습니다.
package com.ktds.cocomo.callapp;
import android.app.Activity;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.os.Build;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
public class PermissionRequester {
public static final int NOT_SUPPORT_VERSION = 2;
public static final int ALREADY_GRANTED = -1;
public static final int REQUEST_PERMISSION = 0;
private Activity context;
private Builder builder;
private void setBuilder(Builder builder) {
this.builder = builder;
}
private PermissionRequester(Activity context) {
this.context = context;
}
public int request(final String permission, final int requestCode, final OnClickDenyButtonListener denyAction) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
int permissionCheck = ContextCompat.checkSelfPermission(context, permission);
if (permissionCheck == PackageManager.PERMISSION_DENIED) {
if (context.shouldShowRequestPermissionRationale(permission)) {
AlertDialog.Builder dialog = new AlertDialog.Builder(context);
dialog.setTitle(builder.getTitle())
.setMessage(builder.getMessage())
.setPositiveButton(builder.getPositiveButtonName(), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
context.requestPermissions(new String[]{permission}, requestCode);
}
}
})
.setNegativeButton(builder.getNegativeButtonName(), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
denyAction.onClick(context);
}
}).create().show();
return REQUEST_PERMISSION;
} else {
context.requestPermissions(new String[]{permission}, requestCode);
return REQUEST_PERMISSION;
}
} else {
return ALREADY_GRANTED;
}
}
return NOT_SUPPORT_VERSION;
}
public static class Builder {
private PermissionRequester requester;
public Builder(Activity context) {
requester = new PermissionRequester(context);
}
private String title = "권한 요청";
private String message = "기능의 사용을 위해 권한이 필요합니다.";
private String positiveButtonName = "네";
private String negativeButtonName = "아니요";
public String getTitle() {
return title;
}
public Builder setTitle(String title) {
this.title = title;
return this;
}
public String getMessage() {
return message;
}
public Builder setMessage(String message) {
this.message = message;
return this;
}
public String getPositiveButtonName() {
return positiveButtonName;
}
public Builder setPositiveButtonName(String positiveButtonName) {
this.positiveButtonName = positiveButtonName;
return this;
}
public String getNegativeButtonName() {
return negativeButtonName;
}
public Builder setNegativeButtonName(String negativeButtonName) {
this.negativeButtonName = negativeButtonName;
return this;
}
public PermissionRequester create() {
this.requester.setBuilder(this);
return this.requester;
}
}
public interface OnClickDenyButtonListener {
public void onClick(Activity activity);
}
}
만든 클래스를 이용해 권한을 요청해보겠습니다.
package com.ktds.cocomo.callapp;
import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int result = new PermissionRequester.Builder(MainActivity.this)
.setTitle("권한 요청")
.setMessage("권한을 요청합니다.")
.setPositiveButtonName("네")
.setNegativeButtonName("아니요.")
.create()
.request(Manifest.permission.CALL_PHONE, 1000, new PermissionRequester.OnClickDenyButtonListener() {
@Override
public void onClick(Activity activity) {
Log.d("xxx", "취소함.");
}
});
if (result == PermissionRequester.ALREADY_GRANTED) {
Log.d("RESULT", "권한이 이미 존재함.");
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_GRANTED) {
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:010-1111-1111"));
startActivity(intent);
}
} else if (result == PermissionRequester.NOT_SUPPORT_VERSION) {
Log.d("RESULT", "마쉬멜로우 이상 버젼 아님.");
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:010-1111-1111"));
startActivity(intent);
} else if (result == PermissionRequester.REQUEST_PERMISSION) {
Log.d("RESULT", "요청함. 응답을 기다림.");
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:010-1111-1111"));
startActivity(intent);
}
}
});
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == 1000) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:010-1111-2222"));
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_GRANTED) {
startActivity(intent);
}
} else {
Toast.makeText(MainActivity.this, "권한요청을 거부했습니다.", Toast.LENGTH_SHORT).show();
}
}
}
}
출처: http://cocomo.tistory.com/393?category=687308 [Cocomo Coding] |